Skip to content

improve time of day transition quality by using Oklab and smoothstep - #509

Merged
nschimme merged 1 commit into
MUME:masterfrom
nschimme:weather-smooth
Apr 8, 2026
Merged

improve time of day transition quality by using Oklab and smoothstep#509
nschimme merged 1 commit into
MUME:masterfrom
nschimme:weather-smooth

Conversation

@nschimme

@nschimme nschimme commented Apr 7, 2026

Copy link
Copy Markdown
Contributor
  • Implement sRGB <-> Linear <-> Oklab conversion in timeofday frag shader.
  • Mix time of day colors in Oklab space for perceptually uniform gradients.
  • Use smoothstep for the time factor in timeofday, atmosphere, and particle shaders to provide non-linear easing during transitions.
  • Synchronize intensity and emissive boost calculations with the new transition curve.

Summary by Sourcery

Improve time-of-day visual transitions and consistency across weather-related shaders

New Features:

  • Interpolate time-of-day colors in Oklab color space for perceptually smoother gradients

Enhancements:

  • Add sRGB, linear, and Oklab color space conversion utilities in the time-of-day fragment shader
  • Apply smoothstep-based easing to time-of-day transitions in time-of-day, atmosphere, and particle shaders
  • Align alpha, intensity, and emissive boost calculations with the new non-linear time-of-day transition curve across shaders

- Implement sRGB <-> Linear <-> Oklab conversion in timeofday frag shader.
- Mix time of day colors in Oklab space for perceptually uniform gradients.
- Use `smoothstep` for the time factor in timeofday, atmosphere, and particle shaders
  to provide non-linear easing during transitions.
- Synchronize intensity and emissive boost calculations with the new transition curve.
@sourcery-ai

sourcery-ai Bot commented Apr 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors time-of-day transitions to use perceptually uniform Oklab color interpolation in the main time-of-day shader and replaces linear time interpolation with smoothstep easing across time-of-day, atmosphere, and particle shaders, while aligning alpha/intensity-based emissive boosts with the new transition curve.

Flow diagram for Oklab color mixing in time of day shader

graph TD
    A[uNamedColors index uTimeOfDay.x] --> B[timeOfDayStartSrgb]
    A2[uNamedColors index uTimeOfDay.y] --> C[timeOfDayTargetSrgb]

    B --> D[srgbToLinear start]
    C --> E[srgbToLinear target]

    D --> F[linearToOklab startOklab]
    E --> G[linearToOklab targetOklab]

    F --> H[mix in Oklab using timeOfDayLerp]
    G --> H

    H --> I[oklabToLinear mixed]
    I --> J[linearToSrgb mixedSrgb]

    subgraph Alpha_and_intensity
        B --> K[timeOfDayStartSrgb alpha]
        C --> L[timeOfDayTargetSrgb alpha]
        K --> M[mix alpha using timeOfDayLerp]
        L --> M
        M --> N[multiply by currentTimeOfDayIntensity]
    end

    J --> O[vFragmentColor rgb]
    N --> O[vFragmentColor alpha]
Loading

File-Level Changes

Change Details Files
Use Oklab color space for time-of-day color interpolation in the main time-of-day fragment shader.
  • Add sRGB-to-linear and linear-to-sRGB conversion helper functions.
  • Add linear RGB to Oklab and Oklab to linear RGB conversion helpers based on matrix transforms and cubic roots/powers.
  • Replace direct vec4 mix of named time-of-day colors with a pipeline that converts sRGB colors to linear, then to Oklab, interpolates in Oklab, and converts back to sRGB for output.
  • Introduce a clamped time parameter and apply smoothstep to produce a non-linear timeOfDayLerp factor used for both color and intensity mixing.
  • Adjust final alpha calculation to interpolate source/target alpha with the eased lerp and multiply by the mixed time-of-day intensity, outputting vec4(mixedSrgb, finalAlpha).
src/resources/shaders/legacy/weather/timeofday/frag.glsl
Apply smoothstep-based easing to time-of-day transitions and decouple alpha/intensity handling in atmosphere and particle shaders.
  • Replace direct clamped linear time-of-day lerp with a two-step tTod computation and smoothstep(0.0, 1.0, tTod) in atmosphere and particle shaders.
  • Change time-of-day alpha handling from mixing full vec4 colors and scaling alpha to mixing only the alpha channels of the named colors and then multiplying by the eased time-of-day intensity.
  • Update emissive boost for fog, clouds, rain, and snow to use the new uTimeOfDayAlpha instead of uTimeOfDayColor.a, keeping behavior consistent with the new alpha/intensity definition.
src/resources/shaders/legacy/weather/atmosphere/frag.glsl
src/resources/shaders/legacy/weather/particle/frag.glsl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The Oklab/sRGB conversion helpers add a fair bit of logic to the time-of-day shader; consider moving these into a shared include or common utility to avoid duplication and keep the main shader focused on the transition logic.
  • After converting back from Oklab to sRGB (mixedSrgb), you may want to explicitly clamp to [0.0, 1.0] to guard against small numerical excursions that could cause banding or artifacts in downstream blending.
  • The time-of-day transition code now uses slightly different variable naming patterns across shaders (t vs tTod, etc.); aligning these for consistency would make it easier to follow and maintain the transition behavior across the different shader stages.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Oklab/sRGB conversion helpers add a fair bit of logic to the time-of-day shader; consider moving these into a shared include or common utility to avoid duplication and keep the main shader focused on the transition logic.
- After converting back from Oklab to sRGB (`mixedSrgb`), you may want to explicitly clamp to `[0.0, 1.0]` to guard against small numerical excursions that could cause banding or artifacts in downstream blending.
- The time-of-day transition code now uses slightly different variable naming patterns across shaders (`t` vs `tTod`, etc.); aligning these for consistency would make it easier to follow and maintain the transition behavior across the different shader stages.

## Individual Comments

### Comment 1
<location path="src/resources/shaders/legacy/weather/timeofday/frag.glsl" line_range="89-90" />
<code_context>
+    vec3 mixedOklab = mix(startOklab, targetOklab, timeOfDayLerp);
+
+    // Convert back to sRGB
+    vec3 mixedSrgb = linearToSrgb(oklabToLinear(mixedOklab));

-    float timeOfDayLerp = clamp((uCurrentTime - uTimeOfDayStartTime) / uTransitionDuration,
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider clamping the final sRGB color to avoid out-of-gamut values from Oklab interpolation.

Oklab interpolation can yield linear RGB outside [0, 1], which converts to out-of-gamut sRGB. If the pipeline isn’t intentionally handling HDR/overbright values, consider clamping the final sRGB result, e.g.:

```glsl
vec3 mixedSrgb = clamp(linearToSrgb(oklabToLinear(mixedOklab)), 0.0, 1.0);
```
This avoids artifacts in later stages that assume normalized color channels.

```suggestion
    // Convert back to sRGB and clamp to valid [0, 1] range to avoid out-of-gamut values
    vec3 mixedSrgb = clamp(linearToSrgb(oklabToLinear(mixedOklab)), 0.0, 1.0);
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +89 to +90
// Convert back to sRGB
vec3 mixedSrgb = linearToSrgb(oklabToLinear(mixedOklab));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Consider clamping the final sRGB color to avoid out-of-gamut values from Oklab interpolation.

Oklab interpolation can yield linear RGB outside [0, 1], which converts to out-of-gamut sRGB. If the pipeline isn’t intentionally handling HDR/overbright values, consider clamping the final sRGB result, e.g.:

vec3 mixedSrgb = clamp(linearToSrgb(oklabToLinear(mixedOklab)), 0.0, 1.0);

This avoids artifacts in later stages that assume normalized color channels.

Suggested change
// Convert back to sRGB
vec3 mixedSrgb = linearToSrgb(oklabToLinear(mixedOklab));
// Convert back to sRGB and clamp to valid [0, 1] range to avoid out-of-gamut values
vec3 mixedSrgb = clamp(linearToSrgb(oklabToLinear(mixedOklab)), 0.0, 1.0);

@nschimme nschimme changed the title use Oklab and smoothstep for time of day transitions improve time of day transition quality by using Oklab and smoothstep Apr 7, 2026
@nschimme
nschimme merged commit 7105144 into MUME:master Apr 8, 2026
18 checks passed
@nschimme
nschimme deleted the weather-smooth branch April 8, 2026 00:13
@codecov

codecov Bot commented Apr 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 25.05%. Comparing base (93d43e3) to head (b26cc87).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #509      +/-   ##
==========================================
- Coverage   25.06%   25.05%   -0.01%     
==========================================
  Files         510      510              
  Lines       42275    42275              
  Branches     4574     4572       -2     
==========================================
- Hits        10596    10594       -2     
- Misses      31679    31681       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant